Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NEW: Stages differ recursive #328

Conversation

mfendeksilverstripe
Copy link
Contributor

@mfendeksilverstripe mfendeksilverstripe commented Mar 11, 2021

Stages differ recursive

  • adds capability to check if an object which owns nested objects needs to be published or not (stages differ recursive)
  • this covers common cases where publishing cascades down to nested objects
  • examples: block page with blocks, complex block such as carousel block with carousel items
  • this feature queries the nested objects based on existing relationship setup so it doesn't add any overhead for the developers to implement any functionality
  • there are two modes available:
    • strong ownership - traverses via owns relation
    • weak ownership - traverses via cascade_duplicates relation

Parent issue

Copy link
Contributor

@maxime-rainville maxime-rainville left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking my understanding of the purpose here. Basically, you want a way to check if recursively publishing a DataObject will lead to any other owned/related Dataobjects to be published as well?

Presumably, this would allow us to have a smarter "dirty" state. e.g.: You have a UserForm page. The UserForm page has no outstanding changes directly applied to it, but one of its form field has been modified. So logically, the UserForm page should be in a dirty state.

src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
@mfendeksilverstripe
Copy link
Contributor Author

@maxime-rainville That's correct, the goal is to have smarter "dirty" state and also allow some level of configuration.

@maxime-rainville
Copy link
Contributor

maxime-rainville commented Apr 6, 2021

From memory, there's a ChangeSet object which is used by publishRecursive. My main concern at this stage is that this PR might be duplicating the ChangeSet logic and/or diverging from it in subtle ways that will create ambiguity down the road. It's probably worth asking ourselves if there's a way we could have some sort of unified logic for both.

@silverstripeux Currently, if you have an object that owns a bunch of child object with unpublished changes, the CMS doesn't show that object in a "dirty" state. If this PR got merge, we would be very close to being able to highlight such a scenario. How much value would you put on this kind of improvement?

e.g.: You have a UserForm page. The UserForm page has no outstanding changes directly applied to it, but one of its form field has been modified. So logically, the UserForm page should be in a dirty state as well.

@clarkepaul
Copy link

@maxime-rainville it does trip CMS users up, they think their page is published and nothing needs to be done further when in-fact deeper content isn't reflected on the published page, hence I would put a lot of value on this. We don't have the ability to train users about this stuff so rely on UI experiences to inform people.

@maxime-rainville
Copy link
Contributor

maxime-rainville commented Apr 6, 2021

@brynwhyman I had a preliminary review. Looks like this has the potential to provide substantial benefit beyond Mojmir's use case.

My main concern would be making sure the chosen approach aligns with the existing logic in ChangeSet.

@mfendeksilverstripe
Copy link
Contributor Author

@maxime-rainville Added an interface for the service as requested.

@brynwhyman
Copy link

Just want to cc @chillu into this pull request too. This sounds like it might overlap some of the work that was done with versioned-snapshots to better understand the state of child objects - admittedly that had more of a focus on the version records, but still...

As an aside, would this PR also resolve this issue? silverstripe/silverstripe-elemental#790

@mfendeksilverstripe
Copy link
Contributor Author

mfendeksilverstripe commented Apr 12, 2021

@brynwhyman Just to provide some context:

Version snapshots it essentially a logger of events, the main drive for this module was to bypass issues with Fluent / Versioned (which are now resolved in Fluent 6), it doesn't provide you with information about state of objects which is the goal of this PR. I don't think there is an overlap here.

The linked Elemental PR is a subcase of the issue which this PR is trying to solve. Note that usage of this feature is also relevant for models outside of blocks.

@brynwhyman
Copy link

Alright, thanks @mfendeksilverstripe that's helpful 😄

@halles
Copy link

halles commented Aug 19, 2021

Does this need more reviewing? I can help out. In the meantime I've patched this with an extension, but this seems much more robust.

FWIW This has been flagged as a bug by clients of ours

@mfendeksilverstripe
Copy link
Contributor Author

@emteknetnz @maxime-rainville This is ready for a review.

@GuySartorelli
Copy link
Member

GuySartorelli commented Oct 9, 2023

As this is adding new functionality, please target this to the 2 branch, rebase against that branch, any resolve and conflicts that might arise.

Copy link
Member

@GuySartorelli GuySartorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't done a full review - but at a glance I have at the very least some questions to clarify the approach and intent.

_config/versionedownership.yml Outdated Show resolved Hide resolved
src/RecursiveStagesInterface.php Outdated Show resolved Hide resolved
src/RecursiveStagesInterface.php Outdated Show resolved Hide resolved
src/RecursiveStagesInterface.php Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
GuySartorelli

This comment was marked as duplicate.

@mfendeksilverstripe mfendeksilverstripe force-pushed the feature/stages-differ-recursive branch from 4797a56 to 97d1ac6 Compare October 9, 2023 03:18
@mfendeksilverstripe mfendeksilverstripe changed the base branch from 1 to 2 October 9, 2023 03:18
src/Versioned.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
@mfendeksilverstripe
Copy link
Contributor Author

Hey @maxime-rainville I would like to get some clarity on what to do with this PR. @GuySartorelli provided me with very good feedback which I'm happy to action. However, from my past experience these PRs even after sinking a lot of effort into them and addressing all the feedback might not get merged because of lack of alignment on how we actually want to approach this problem.

This is my understanding of the situation:

From the feedback I see two distinct groups of changes:

  • long term solution which redefines how ownership is managed - this is CMS 6 stuff the earliest
  • workaround solution for CMS 4 / 5 - something that we can deliver now

Please let me know which of these (if any) should this PR focus on.

Copy link
Member

@emteknetnz emteknetnz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall approach seems logical, recursively traverse down the $owns (or other ownership config) tree and looks for unpublished changes

So the intention with this PR is to set the initial state of the Page Publish button to the results of Versioned::stagesDifferRecursive()?

Just to confirm, is the main issue you're having with the Page Publish button being out of sync related its initial state on page load, or is it it after changes are made i.e. the javascript changed detection doesn't work on nested things?

@mfendeksilverstripe
Copy link
Contributor Author

Hey @emteknetnz This change is aiming to address the issues related to initial page state only. Yes, we would need to update several places in the CMS UI where stagesDiffer() is used and replace it with stagesDifferRecursive() to achieve that. Most notable places would be the publish button state but also other components such as Cancel draft changes action.

I recognise that there are other issues with the publish button state and cancel draft changes action which are caused by user interaction. Most notable case is the usage of block level edit in the elemental inline editor. These issues are out of scope of this PR though.

@emteknetnz
Copy link
Member

Cancel draft changes action

What's a cancel draft changes action?

@mfendeksilverstripe
Copy link
Contributor Author

What's a cancel draft changes action?

@emteknetnz Please check on silverstripe/silverstripe-cms#2892 , I left more details there.

@emteknetnz
Copy link
Member

emteknetnz commented Oct 14, 2023

OK cool thanks, so it's intended use case is limited to a couple of things that are both calculated in SiteTree::getCMSActions(). Hopefully should be easy to rollout then

From the feedback I see two distinct groups of changes:
long term solution which redefines how ownership is managed - this is CMS 6 stuff the earliest
workaround solution for CMS 4 / 5 - something that we can deliver now

I think treating this PR as a "workaround" PR is fine, IMO it's not really a workaround it's almost a bugfix to get the existing architecture (which was probably designed pre-elemental) to work as it should. My only real concern is that there will be a performance hit on this, particularly if you have a large number of blocks. I'm not sure how impactful this would be in practice though, it may be negligible.

I'd agree with Guy that this should just go straight into Versioned rather than having a separate service class. While I get that the intention is to split things off in to easily digestable pieces, it just make it things inconsistent because all the existing stuff in Versioned just stays where it is. I'd much rather just keep adding to Versioned for now.

@mfendeksilverstripe
Copy link
Contributor Author

mfendeksilverstripe commented Oct 16, 2023

Agreed to remove the cascade_duplicates based traversal - we will only use owns which is consistent with publishRecursive()

  • add test for versioned model > non-versioned model > versioned model

@mfendeksilverstripe mfendeksilverstripe force-pushed the feature/stages-differ-recursive branch from eb048d5 to d2efe5a Compare October 17, 2023 01:21
@mfendeksilverstripe
Copy link
Contributor Author

@GuySartorelli I've pushed up new changes as per our discussion, please review.

cc: @maxime-rainville

Copy link
Member

@GuySartorelli GuySartorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regarding @throws in phpdocs - I notice you have added that in many methods which themselves don't actually throw the exception. That doesn't tend to be the way @throws is used in Silverstripe CMS.

Can you please provide some information about why those are being added in this way? With citations preferably if it's a common practice.

I have added some notes below on the assumption that you're right that they should be here - but I'd like to understand why they should be there if they indeed should.

For NotFoundExceptionInterface specifically, I'm assuming that's coming from the injector. Please don't add a throws statement for that, especially when we're explicitly defining the service that we're requesting. Otherwise we'd have to add this throws statement to basically every method across all the supported modules, since injector is used for basically everything.

src/RecursiveStagesExtension.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
Copy link
Member

@GuySartorelli GuySartorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall looks good. There's just a couple of clarifying questions here.

We also won't fully know if this is fit for purpose until we start on silverstripe/silverstripe-admin#1593 but whoever picks that up can make whatever adjustments are necessary if there's anything we missed here, so I'm okay merging as-is once the questions below are answered.

src/RecursiveStagesService.php Outdated Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
src/RecursiveStagesService.php Show resolved Hide resolved
@mfendeksilverstripe
Copy link
Contributor Author

Hey @GuySartorelli I believe I addressed all the feedback from you. Please hit me up if there are more things to follow up on 😉

@GuySartorelli
Copy link
Member

Just the one requested change - then I'll be happy to merge.

Copy link
Member

@GuySartorelli GuySartorelli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks!

@GuySartorelli GuySartorelli merged commit 79bfcc4 into silverstripe:2 Oct 30, 2023
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants